DataManager = DataManager or Class("DataManager", EventDispatcher)
DataEvent = RegisterEvents{
    "Reload"
}
---@diagnostic disable-next-line: duplicate-set-field
function DataManager:ctor()
    EventDispatcher.ctor(self)
    self.configManager = ConfigManager.new()
    self.propIdCreator = IdCreator.new(1)
    self.instanceIdCreator = IdCreator.new(DataTypeMax + 1)
    self.argIdCreator = IdCreator.new(1)
    self._tpls = {}
    self.rootTemplate = self:createDataTemplate()
    self.root = self.rootTemplate:createDataTable()
    self.updateDuration = 0.016
    self.stepCount = 0
    self.timeCount = 0
    self._changeEventIdCreator = IdCreator.new()
    self._idToDataTable = {}
    DataSystem:addDataManager(self)
end

function DataManager:createDataTemplate()
    local tpl = DataTableTemplate.new(self)
    self._tpls[tpl.id] = tpl
    return tpl
end

function DataManager:getDataTemplate(id)
    return self._tpls[id]
end

function DataManager:getDataTable(tplId, dataTableId)
    local tpl = self:getDataTemplate(tplId)
    return tpl:getDataTable(dataTableId)
end

function DataManager:createPropId()
    return self.propIdCreator:create()
end
function DataManager:createInstanceId()
    return self.instanceIdCreator:create()
end

function DataManager:createArgId()
    return self.argIdCreator:create()
end

function DataManager:update(dt)
    self.timeCount = self.timeCount + dt
    while(self.timeCount > (self.stepCount + 1) * self.updateDuration ) do
        self:updateStep()
    end
end

function DataManager:updateStep()
    self.stepCount = self.stepCount + 1
end

function DataManager:_setDirty(dataId)
    local dataTable = self._idToDataTable[dataId]
    dataTable:setDirty(dataId)
    local listeners = self._subscribes[dataId]
    if not listeners then
        return
    end
    for id, _ in pairs(listeners) do
        self:_setDirty(id)
    end
end

function DataManager:getSaveData()
    local data = {}
    local config = self.configManager:getSaveData()
    data.config = config
    return data
end

function DataManager:clear()
    
end

function DataManager:fromJson(json)
    self:clear()
    self.configManager:fromJson(json.config)
    self:emit(DataEvent.Reload)
end